﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace testqwe
{
    //实现整张板材的排样方式
    class Plate
    {
        int lenght;
        int width;
        int[] diameter;
        double[] value;
        public double revalue;
        public double reval;
        public int[] P;
        Trapezoid_stripe[] t_s;
        Stripe[] p_s;
        //List类型中保存的都是排样方案的信息
        public List<int[]> t_pattern; //左边梯形的排样方式
        public List<int[]> t_patternforright; //右边梯形的排样方式
        public List<int[]> p_pattern; //中间平行四边形的排样方式
        public int pattern_type;
        //记录两条分割线的位置
        public int divid_line; 
        public int divid_lineoft;
        public Plate(int l,int w,int[] d,double[] v,Trapezoid_stripe[] ts, Stripe[] ps)
        {
            lenght=l;
            width = w;
            diameter = d;
            value = v;
            P = new int[Constant.BLK_NUM];
            t_s = ts;
            p_s = ps;
            t_pattern = new List<int[]>();
            t_patternforright = new List<int[]>();
            p_pattern = new List<int[]>();
            pattern_type = -1;
            divid_line = -1;
            divid_lineoft = -1;
        }

        public void getPattern(int i)
        {
            if (i == 1)
            {
                enumPattern();//不对称排样
                
            }
            else if (i == 3)
            {
               // Recpattern();
                //do nothing
            }
            else
            {
                Parapattern();//对称排样
            }
            
        }

        //对称排样方式
        private void Parapattern()
        {
            double hypotenuse = width * Constant.THIRD_OF_SQRT_THREE;
            int maxupper = (int)((lenght - hypotenuse) / 2);
            double max = 0.0;
            int[] r1 = new int[Constant.BLK_NUM];
            int[] r2 = new int[Constant.BLK_NUM];
            for (int i = 0; i <= maxupper; i++)
            {
                //调用梯形排样得到其结果
                Right_trapezoid rt = new Right_trapezoid(i, width, diameter, value,t_s);
                rt.docompelx();
                double n1 = rt.revalue*2;


                //调用平行四边形排样得到其结果
                Parallelogram para = new Parallelogram((int)(lenght-2*i-hypotenuse), width, diameter, value,p_s);
                para.start();
                double n2 = para.revalue;

                //保证是得到当前最优排样方式
                if (n1 + n2 > max)
                {
                    max = n1 + n2;
                    r1 = rt.result;
                    r2 = para.result;
                    pattern_type = para.directiontype;
                    t_pattern = rt.pattern;
                    p_pattern = para.pattern;
                    divid_line = i;
                }
            }
            revalue = max;
            reval = 0.0;
            //保存最优排样方式中，各种毛坯的数量
            for (int i = 0; i < Constant.BLK_NUM; i++)
            {
                P[i] += (r2[i]+r1[i]*2);
                reval += P[i] * value[i];
            }
        }


        //不对称排样方式
        private void enumPattern()
        {
            double hypotenuse = width * Constant.THIRD_OF_SQRT_THREE;
            int maxLength = (int)(lenght - hypotenuse); //梯形段的上底最大长度
            List<List<int[]>> pList = new List<List<int[]>>();//存储每种梯形块的排样图
            List<double> tValue=new List<double>();//存储每种梯形块的价值
            List<int[]> tResult = new List<int[]>();//存储每种梯形块中每种毛坯的个数
            for (int s = 0; s <= maxLength; s++)//遍历每种可能的上底长
            {
                Right_trapezoid rt = new Right_trapezoid(s, width, diameter, value, t_s);
                rt.docompelx();
                pList.Add(rt.pattern);
                tValue.Add(rt.revalue);
                tResult.Add(rt.result);
            }
            int normalLenCount = Constant.nomalLength.Count;//规范长度的个数
            double max = 0.0;
            int[] r1 = new int[Constant.BLK_NUM]; //保存左边梯形中包含的各种毛坯的个数
            int[] r2 = new int[Constant.BLK_NUM]; //保存中间平行四边形中包含的各种毛坯的个数
            int[] r3 = new int[Constant.BLK_NUM]; //保存右边梯形中包含的各种毛坯的个数
            int maxValueLocation = -1;
            for (int i = 0; i <normalLenCount; i++)  //遍历每个规范长度
            {
                int paraLen = Constant.nomalLength[i];
                int restLen =(int) (lenght - paraLen - hypotenuse);//最大的梯形上底长度
                int times = (int)(restLen / 2 + 0.99);
                double tmaxValue = 0.0;
                for (int j = 0; j <= times; j++)  //遍历可能的梯形
                {
                    int restUpper =restLen - j ;
                    if (tValue[j] + tValue[restUpper] > tmaxValue)
                    {
                        tmaxValue = tValue[j] + tValue[restUpper];
                        maxValueLocation = j;
                    }
                }

                Parallelogram para = new Parallelogram(paraLen, width, diameter, value, p_s);
                para.start();
                double n2 = para.revalue;
                if (tmaxValue + n2 > max)
                {
                    max = tmaxValue + n2;
                    
                    r2 = para.result;
                    pattern_type = para.directiontype;
                    p_pattern = para.pattern;
                    
                    divid_line = paraLen + maxValueLocation;
                    //得到左边的分割线
                    divid_lineoft = maxValueLocation;
                }
            }
            revalue = max;
            t_pattern = pList[divid_lineoft];
            
            r1 = tResult[divid_lineoft];

            int tRight=(int)(lenght - divid_line  - hypotenuse);
            t_patternforright = pList[tRight];
           
            r3 = tResult[tRight];
            reval = 0.0;
            //保存最优排样方式中，各种毛坯的数量
            for (int i = 0; i < Constant.BLK_NUM; i++)
            {
                P[i] += (r2[i] + r1[i]+r3[i]);
                reval += P[i] * value[i];
            }
        }

    }
}
